package com.jt;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.*;
import redis.clients.jedis.params.SetParams;

import java.util.*;

/**
 * 需要访问redis需要做以下操作
 * 1.关闭linux防火墙 service iptables stop(临时关闭)
 * 2.检查redis.conf中的配置文件,ip绑定是否注释,关闭保护模式,开启后台启动
 * 3.redis-server redis.conf
 * @author dc
 * @Classname testRedis
 * @Date 2020/2/17 15:19
 */
public class testRedis {

    Jedis jedis = null;

    @BeforeEach
    public void init(){
        String host = "192.168.1.103";
        int port = 6379;
        jedis = new Jedis(host,port);
    }


    /**
     * 利用redis自己的API暂时不用和Spring整合
     */
    @Test
    public void testString(){
        String result = jedis.set("1910", "抗击疫情人人有责");
        System.out.println(result);
        System.out.println(jedis.get("1910"));
    }

    /**
     * 业务说明:
     * 如果redis中已经存在了key,那我们则不允许赋值
     * redis方法介绍:
     * 1.利用exists判断实现赋值
     * 2.利用setnx方式进行判断
     */
    @Test
    public void testString02(){
        //1.判断一个key是否存在
        if(!jedis.exists("1910")){
            jedis.set("1910","测试赋值是否成功");
        }
        System.out.println(jedis.get("1910"));
    }

    /**
     * 使用setnx,如果key不存在则执行set操作,否则不执行
     */
    @Test
    public void testString03(){
        jedis.setnx("1910","测试setnx");
        System.out.println(jedis.get("1910"));
    }

    /**
     * 原子性操作:要求赋值和超时时间的设定同时完成
     * 使用setex为key添加超时时间
     */
    @Test
    public void testString04() throws InterruptedException {
        jedis.setex("1910",10,"保证原子性的超时时间测试");
        Thread.sleep(5000);
        System.out.println(jedis.ttl("1910"));
    }

    /**
     * 需求:进行操作和添加超时时间同时完成,并不允许修改已有数据
     * 问题说明:
     * setnx:可以实现不修改已有数据
     * setex:可以实现赋值和超时时间操作
     * 但是上述的操作不能同时完成
     */
    @Test
    public void testString05(){
        SetParams params = new SetParams();
        params.ex(10).nx();
        //满足赋值和超时的原子性操作
        jedis.set("1910","String类型的终极测试",params);
        System.out.println(jedis.get("1910"));
    }

    /**
     * 操作hash数据类型
     * 如果有一类数据需要redis保存就可以用hash类型
     */
    @Test
    public void testHash(){
        jedis.hset("user","id","1");
        jedis.hset("user","name","张三");
        Map<String,String> userMap=jedis.hgetAll("user");
        System.out.println(userMap);
    }

    /**
     * 测试redis队列操作
     */
    @Test
    public void testList(){
        jedis.lpush("ids","1","2");
        System.out.println(jedis.lpop("ids"));
    }

    /**
     * redis中的事务是弱事务
     * 使用redis事务一般不会级联
     */
    @Test
    public void testTX(){
        //1.开启事务
        Transaction transaction = jedis.multi();
        try {
            transaction.set("a","aa");
            transaction.set("b","bb");
            transaction.exec();
            System.out.println(jedis.get("a")+","+jedis.get("b"));
        } catch (Exception e) {
            e.printStackTrace();
            transaction.discard();
        }
    }

    /**
     * 配置分片
     */
    @Test
    public void testShards(){
        List<JedisShardInfo> shards = new ArrayList<>();
        shards.add(new JedisShardInfo("192.168.1.103",6379));
        shards.add(new JedisShardInfo("192.168.1.103",6380));
        shards.add(new JedisShardInfo("192.168.1.103",6381));
        ShardedJedis shardedJedis = new ShardedJedis(shards);
        shardedJedis.set("1910","分片测试");
        System.out.println(shardedJedis.get("1910"));
    }

    /**
     * 配置redis哨兵
     */
    @Test
    public void testSentinel(){
        String masterName = "mymaster" ;
        //准备哨兵的集合配置 ip,port
        Set<String> sentinels = new HashSet<>();
        sentinels.add("192.168.1.103:26379");
        JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName,sentinels);
        Jedis jedis = sentinelPool.getResource();   //从池中动态获取
        jedis.set("1910","哨兵操作正确");
        System.out.println(jedis.get("1910"));
        jedis.close();
    }

    /**
     * 实例化集群对象
     */
    @Test
    public void testCluster(){
        Set<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.1.103",7000));
        nodes.add(new HostAndPort("192.168.1.103",7001));
        nodes.add(new HostAndPort("192.168.1.103",7002));
        nodes.add(new HostAndPort("192.168.1.103",7003));
        nodes.add(new HostAndPort("192.168.1.103",7004));
        nodes.add(new HostAndPort("192.168.1.103",7005));
        JedisCluster cluster = new JedisCluster(nodes);
        cluster.set("1910","redis集群操作成功!");
        System.out.println(cluster.get("1910"));
    }

}
